package com.jichangxiu.framework.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.LambdaUtils;
import com.jichangxiu.common.entity.bo.CompareResult;
import com.jichangxiu.common.utils.ObjUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class CompareUtils {

    public static <E, T> CompareResult<E> compareList(List<E> uiList, List<E> dbList, SFunction<T, ?> fn) {
        String fieldName = LambdaUtils.getName(fn);
        if (StrUtil.isEmpty(fieldName)) {
            fieldName = "id";
        }
        List<E> addList = new ArrayList<>();
        List<E> editList = new ArrayList<>();
        List<E> deleteList = new ArrayList<>();
        // 如果前端传来的，和数据库里面的都是空的
        if (ObjectUtil.isEmpty(uiList) && ObjectUtil.isEmpty(dbList)) {
            // 如果两者都是空的则什么都不做
            log.info("本次比较无需操作");
        }
        // 如果前端传来的不是空的，数据库里面的是空的
        else if (ObjectUtil.isNotEmpty(uiList) && ObjectUtil.isNotEmpty(dbList)) {
            // 如果两者都不是空的
            // 循环页面上的所有数据，判断是否为新增的
            for (E ui : uiList) {
                // 如果 ID 不存在，就说明肯定是新增的。
                Object uiId = ObjUtils.getFieldValue(ui, fieldName);
                if (ObjectUtil.isEmpty(uiId)) {
                    // 新增的
                    addList.add(ui);
                } else {
                    // 如果存在 ID 就需要比对数据库数据。
                    // 代表不在数据库中存在，需要新增
                    boolean isExist = false;
                    for (E db : dbList) {
                        Object dbId = ObjUtils.getFieldValue(db, fieldName);
                        if (ObjectUtil.equals(uiId, dbId)) {
                            // ID 匹配上了，代表在数据库中存在，需要修改
                            isExist = true;
                        }
                    }
                    // 经过循环，最终发现，不在数据库中存在
                    if (!isExist) {
                        addList.add(ui);
                    } else {
                        // 在数据库中存在就代表是编辑的
                        editList.add(ui);
                    }
                }
            }
            // 循环数据库中的所有数据，判断是否被删除了
            for (E db : dbList) {
                Object dbId = ObjUtils.getFieldValue(db, fieldName);
                // 设置一个默认值，代表在页面中不存在，需要删除
                boolean isDelete = false;
                for (E ui : uiList) {
                    Object uiId = ObjUtils.getFieldValue(ui, fieldName);
                    // 如果 页面ID 不存在，就跳过
                    if (ObjectUtil.isEmpty(uiId)) {
                        continue;
                    }
                    // 如果 ID 匹配上了，代表在页面中存在
                    if (ObjectUtil.equals(dbId, uiId)) {
                        // 代表在页面中存在，不需要删除
                        isDelete = true;
                    }
                }
                // 经过循环，最终发现，不在页面中存在
                if (!isDelete) {
                    deleteList.add(db);
                }
            }
        }
        // 如果前端传来的是空的，数据库里面的不是空的
        else if (ObjectUtil.isEmpty(uiList) && ObjectUtil.isNotEmpty(dbList)) {
            // 页面传过来是空的，则需要把数据库中所有已经存在的数据全部删除
            deleteList.addAll(dbList);
        }
        // 如果前端传来的不是空的，数据库里面的是空的
        else if (ObjectUtil.isNotEmpty(uiList) && ObjectUtil.isEmpty(dbList)) {
            // 如果页面传过来的不是空的，而数据库中尚未保存数据，则将页面传过来的全部保存
            addList.addAll(uiList);
        }
        CompareResult<E> compareResult = new CompareResult<E>();
        compareResult.setAddList(addList);
        compareResult.setEditList(editList);
        compareResult.setDeleteList(deleteList);
        return compareResult;
    }

}
